home *** CD-ROM | disk | FTP | other *** search
/ Aminet 48 / Aminet 48 (2002)(GTI - Schatztruhe)[!][Apr 2002].iso / Aminet / docs / misc / MemManual.lha / MemManual / C_Sources / mmap.c next >
Encoding:
C/C++ Source or Header  |  2002-02-09  |  9.4 KB  |  267 lines

  1. /*************************************************
  2.  ** mmap                                        **
  3.  **                                             **
  4.  ** sample file-memory mapping using the        **
  5.  ** memory.library                              **
  6.  ** © 2001 THOR Software, Thomas Richter        **
  7.  *************************************************/
  8.  
  9. /// Includes
  10. #include <exec/types.h>
  11. #include <exec/libraries.h>
  12. #include <exec/memory.h>
  13. #include <utility/tagitem.h>
  14. #include <mmu/mmutags.h>
  15. #include <memory/memory.h>
  16. #include <memory/memtags.h>
  17. #include <dos/dos.h>
  18. #include <dos/rdargs.h>
  19. #include <string.h>
  20.  
  21. #include <proto/memory.h>
  22. #include <proto/exec.h>
  23. #include <proto/mmu.h>
  24. #include <proto/dos.h>
  25. ///
  26. /// Defines
  27. #define TEMPLATE "INPUTFILE/A"
  28.  
  29. #define ARG_FILE        0L
  30. #define ARG_NUM         1L
  31. ///
  32. /// Statics
  33. char version[]="$VER: mmap 40.1 (9.2.2002) © THOR";
  34. struct ExecBase *SysBase;
  35. struct MemoryLibrary *MemoryBase;
  36. struct MMUBase *MMUBase;
  37. struct DosLibrary *DOSBase;
  38. ///
  39. /// Protos
  40. int __asm __saveds main(void);
  41. int MMapTest(char *name);
  42. struct MMap *MapFile(char *filename,BOOL readonly);
  43. void UnmapFile(struct MMap *);
  44. ///
  45. /// Structures
  46. /*
  47.  * Use this structure to identify an mmap'd memory area
  48.  * Note that this example is only capable to mmap one file into memory,
  49.  * more sophisticated programs will be able to do more.
  50.  */
  51. struct MMap {
  52.         struct AdrSpace         *adr;           /* address space defining the remapping */
  53.         struct MMUContext       *ctx;           /* underlying MMU context */
  54.         struct VMPool           *pool;          /* pool within the address space holding the file */
  55.         APTR                     lower;         /* logical base address of the file */
  56.         ULONG                    size;          /* size of the file in bytes */
  57. };
  58. ///
  59.  
  60. /// main
  61. int __asm __saveds main(void)
  62. {
  63. struct RDArgs *rd;
  64. LONG args[ARG_NUM];
  65. int rc = 25;
  66.  
  67.         SysBase = *((struct ExecBase **)(4L));
  68.         memset(args,0,sizeof(args));
  69.  
  70.         if (DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",37)) {
  71.                 if (MMUBase = (struct MMUBase *)OpenLibrary("mmu.library",43)) {
  72.                         if (MemoryBase = (struct MemoryLibrary *)OpenLibrary("memory.library",0)) {
  73.                                 Printf("memory.library successfully openend.\n");
  74.                                 if (rd = ReadArgs(TEMPLATE,args,NULL)) {
  75.                                         rc = MMapTest((char *)args[ARG_FILE]);
  76.                                         FreeArgs(rd);
  77.                                 } else {
  78.                                         PrintFault(IoErr(),"mmap failed");
  79.                                 }
  80.                                 CloseLibrary((struct Library *)MemoryBase);
  81.                         } else {
  82.                                 Printf("mmap failed: Failed to open the memory.library.\n");
  83.                         }
  84.                         CloseLibrary((struct Library *)MMUBase);
  85.                 } else {
  86.                         Printf("mmap failed: Failed to open the mmu.library V43.");
  87.                 }
  88.                 CloseLibrary((struct Library *)DOSBase);
  89.         }
  90.  
  91.         return rc;
  92. }
  93. ///
  94. /// MapFile
  95. struct MMap *MapFile(char *file,BOOL readonly)
  96. {
  97. struct MMap *map;
  98.  
  99. /* we first build a new map structure, then fill it out */
  100.  
  101.         map = AllocVec(sizeof(struct MMap),MEMF_PUBLIC|MEMF_CLEAR);
  102.         if (map) {
  103.                 BPTR lock;
  104.                 struct FileInfoBlock *fib;
  105.                 /*
  106.                  * get now the size of the file
  107.                  * we need the file size. The memory.library cannot provide it
  108.                  * since it has to round to entire page sizes by
  109.                  * construction.
  110.                  */
  111.  
  112.                 lock = Lock(file,SHARED_LOCK);
  113.                 if (lock) {
  114.                         fib = AllocDosObject(DOS_FIB,TAG_DONE);
  115.  
  116.                         if (fib) {
  117.                                 if (Examine(lock,fib)) {
  118.                                         map->size = fib->fib_Size;
  119.                                 }
  120.                                 FreeDosObject(DOS_FIB,fib);
  121.                         }
  122.                         UnLock(lock);
  123.                 }
  124.  
  125.                 if (map->size) {
  126.                         /* Build a new MMU context that is shared from the current
  127.                          * context.
  128.                          */
  129.                         map->ctx = CreateMMUContext(MCXTAG_SHARE,DefaultContext(),
  130.                                                     TAG_DONE);
  131.  
  132.                         if (map->ctx) {
  133.                                 /* Build a new address space on top of the context
  134.                                  */
  135.                                 map->adr = NewAdrSpace(
  136.                                                 /* MEMTAG_VMSWAPTYPE,MEMFLAG_SWAPPART,
  137.                                                  * MEMTAG_SWAPPARTNAME,"ZIP:",
  138.                                                  */
  139.                                                 MEMTAG_CONTEXT,map->ctx,
  140.                                                 MEMTAG_VMSWAPTYPE,MEMFLAG_SWAPFILE,
  141.                                                 MEMTAG_SWAPFILENAME,file,
  142.                                                 MEMTAG_KEEPFILE,TRUE,
  143.                                                 MEMTAG_FIXEDSIZE,TRUE,
  144.                                                 MEMTAG_READONLY,readonly,
  145.                                                 MEMTAG_PREDEFINED,TRUE,
  146.                                                 TAG_DONE);
  147.  
  148.                                 if (map->adr) {
  149.                                         /*
  150.                                          * now enter the addres space
  151.                                          */
  152.                                         if (EnterAddressSpace(map->adr,NULL)) {
  153.  
  154.                                                 /*
  155.                                                  * build a memory pool within the address space
  156.                                                  */
  157.  
  158.                                                 map->pool = NewVMPool(
  159.                                                         MEMTAG_FIXEDSIZE,TRUE,
  160.                                                         MEMTAG_PREDEFINED,TRUE,
  161.                                                         MEMTAG_READONLY,readonly,
  162.                                                         MEMTAG_PREALLOC,TRUE,
  163.                                                         MEMTAG_PROVIDESMEM,FALSE,
  164.                                                         TAG_DONE);
  165.  
  166.  
  167.                                                 if (map->pool) {
  168.                                                         /*
  169.                                                          * compute the lower edge of the
  170.                                                          * memory pool
  171.                                                          */
  172.                                                         map->lower = PoolVBase(map->pool);
  173.  
  174.                                                         return map;
  175.                                                 }
  176.  
  177.                                                 LeaveAddressSpace(NULL);
  178.                                         }
  179.                                         DeleteAdrSpace(map->adr);
  180.                                 }
  181.  
  182.                                 DeleteMMUContext(map->ctx);
  183.                         }
  184.                 }
  185.                 FreeVec(map);
  186.         }
  187.  
  188.         return NULL;
  189. }
  190. ///
  191. /// UnmapFile
  192. void UnmapFile(struct MMap *map)
  193. {
  194.  
  195.         if (map) {
  196.                 if (map->pool)  DeleteVMPool(map->pool);
  197.                 if (map->adr) {
  198.                         LeaveAddressSpace(NULL);
  199.                         DeleteAdrSpace(map->adr);
  200.                 }
  201.                 if (map->ctx)   DeleteMMUContext(map->ctx);
  202.  
  203.                 FreeVec(map);
  204.         }
  205. }
  206. ///
  207. /// MMapTest
  208. int MMapTest(char *name)
  209. {
  210. int rc = 10;
  211. struct MMap *map;
  212.  
  213.  
  214.         if (map = MapFile(name,TRUE)) {
  215.                 ULONG len;
  216.                 UBYTE *p;
  217.  
  218.                 Printf("MMap base address is: 0x%08lx\n",map->lower);
  219.  
  220.                 p = map->lower;
  221.                 len = map->size;
  222.  
  223.                 {
  224.                         UBYTE c = *p;
  225.  
  226.                         Printf("First character is %lc\n",c);
  227.  
  228.                         HoldMemory(map->adr,p,2<<12);
  229.                         UnholdMemory(map->adr,p,2<<12,FALSE);
  230.                 }
  231.  
  232.                 do {
  233.                         UBYTE buf[256+2];
  234.                         UBYTE *q = buf;
  235.                         ULONG sz = 0L;
  236.  
  237.                         /* advance the pointer to the next LF
  238.                          * Note that we *MUST* copy the data over
  239.                          * before we pass it out to the Os. Delivering
  240.                          * virtual memory to *ANY* Os function is
  241.                          * illegal.
  242.                          */
  243.  
  244.                         while(len && sz<256) {
  245.                                 UBYTE c;
  246.                                 c    = *p++;
  247.                                 *q++ = c;
  248.                                 len--;
  249.                                 sz++;
  250.  
  251.                                 if (c == '\n' || c == '\0')
  252.                                         break;
  253.                         }
  254.                         *q = 0;
  255.                         Printf("%s",buf);
  256.                 } while(len);
  257.  
  258.                 rc = 0;
  259.  
  260.                 UnmapFile(map);
  261.         } else Printf("mmap failed: Could not mmap file.\n");
  262.  
  263.         return rc;
  264. }
  265. ///
  266.  
  267.